package com.spsy.pay.controller;

import com.alibaba.fastjson.JSON;
import com.spsy.common.core.domain.R;
import com.spsy.order.api.SpsyOrderProvider;
import com.spsy.pay.constant.MqConstant;
import com.spsy.pay.domain.Pay;
import com.spsy.pay.order.CommUtil;
import com.spsy.pay.order.Constants;
import com.spsy.pay.order.XMLUtil;
import com.spsy.pay.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: liuzhiping
 * @date: 2024/12/12 21:35
 **/
@RestController
@Slf4j
@CrossOrigin
@RequestMapping(value = "/pay")
public class WeixinPayNotifyController {


    @Autowired
    private SpsyOrderProvider spsyOrderProvider;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /*@RequestMapping(value="weixin/notify",method= RequestMethod.POST, produces = {"application/xml; charset=UTF-8"})
    public void notifyFromWx(HttpServletRequest request, HttpServletResponse response) {
        log.info("==========>微信回到接口。。。。。白杨支付成功回调");
    }*/

    @Autowired
    private IPayService iPayService;




    /**
     * 微信回调
     * @return
     */
    @RequestMapping(value="weixin/notify2")
    public R asyncNotifyFromWx2() {
        //回调告知订单系统Todo:
        /*String orderId = "1000010";
        R r = spsyOrderProvider.pay2OrderNoity(orderId);*/
        String orderId = "55";

        //订单id和状态，放入rabbitmq中
        Map<String,String> mapStr = new HashMap<String,String>();
        mapStr.put("orderId",orderId);
        mapStr.put("orderStatus","2");
        //发送订单数据
        this.rabbitTemplate.convertAndSend(MqConstant.EXCHANGE_NAME,MqConstant.KEY_NAME, com.alibaba.fastjson2.JSON.toJSONString(mapStr));

        return  R.ok();
    }


    /**
     * 微信回调
     * @return
     */
    @RequestMapping(value="weixin/notify",method= RequestMethod.POST, produces = {"application/xml; charset=UTF-8"})
    public void asyncNotifyFromWx(HttpServletRequest request, HttpServletResponse response) {
        String uuid = "1sdfasdfasdfasdf";
        long start = System.currentTimeMillis();
        int retunCode = 0;
        String msg = "";

        StringBuilder builder = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = request.getReader();
            String str = "";
            while((str = reader.readLine()) != null){
                builder.append(str);
            }
            log.info("====notify wx 微信回调222【开始】 uuid={},data={}",uuid,builder.toString());






            /***
             * <xml>
             * <appid><![CDATA[wxbbac76fb81c710c6]]></appid>
             * <bank_type><![CDATA[CFT]]></bank_type>
             * <cash_fee><![CDATA[1]]></cash_fee>
             * <fee_type><![CDATA[CNY]]></fee_type>
             * <is_subscribe><![CDATA[N]]></is_subscribe>
             * <mch_id><![CDATA[1548473611]]></mch_id>
             * <nonce_str><![CDATA[eed46ee215b849a7806012498c1b8056]]></nonce_str>
             * <openid><![CDATA[oZAf_jjxQKRJHv2BVHluoizFoUIM]]></openid>
             * <out_trade_no><![CDATA[order620191028161608XYTVSZGJEJ000001]]></out_trade_no>
             * <result_code><![CDATA[SUCCESS]]></result_code>
             * <return_code><![CDATA[SUCCESS]]></return_code>
             * <sign><![CDATA[DEDE8DC07012C69A18824A9523843F40]]></sign>
             * <time_end><![CDATA[20191028161652]]></time_end>
             * <total_fee>1</total_fee>
             * <trade_type><![CDATA[APP]]></trade_type>
             * <transaction_id><![CDATA[4200000409201910286163121037]]></transaction_id>
             * </xml>
             */
            /*ResultData resultData = this.notifyReceiveWxService.doNotify(uuid,builder.toString());*/

            Map<String,String> map = XMLUtil.doXMLParse(builder.toString());
            log.info("====notify wx 微信结果【结束】 map={}",JSON.toJSONString(map));

            String orderId = map.get("out_trade_no");


            //订单id和状态，放入rabbitmq中
            Map<String,String> mapStr = new HashMap<String,String>();
            mapStr.put("orderId",orderId);//orderId=a100
            mapStr.put("orderStatus","2");//状态是成功：2
            //发送订单数据
            this.rabbitTemplate.convertAndSend(MqConstant.EXCHANGE_NAME,MqConstant.KEY_NAME,mapStr);

          /*  //回调告知订单系统Todo:
            R r = spsyOrderProvider.pay2OrderNoity(orderId);*/

            //通过订单oderId 修改订单状态 //todo:
            Pay pay = Pay.builder()
                    .orderId(orderId)
                    .payStatus(Long.parseLong("2"))
                    .productId("八维")
                    .build();
            /*Pay pay = new Pay();
            pay.setOrderId(orderId);
            pay.setPayStatus(Long.parseLong("2"));*/

            int updateCount = this.iPayService.updateByOrderId(pay);

            String weixinSign = map.get("sign");
            String selfSign = CommUtil.genSign(map, Constants.API_KEY,"MD5");

            if(!weixinSign.equals(selfSign)){
                //------返回
                PrintWriter out = null;
                try {
                    String returnCode = retunCode==200 ?"SUCCESS":"FAIL";
                    builder = new StringBuilder();
                    response.setContentType("text/xml;charset=utf-8");
                    out = response.getWriter();
                    builder.append("<xml>\n");
                    builder.append("  <return_code><![CDATA["+returnCode+"]]></return_code>\n");
                    builder.append("	<return_msg><![CDATA["+msg+"]]></return_msg>\n");
                    builder.append("</xml>\n");

                    log.info("=====返回数据 sb={}",builder.toString());
                    out.write(builder.toString());
                    out.flush();
                } catch (IOException e) {

                    log.error("=====notify->from->wx error("+uuid+"):"+e.getMessage(),e);
                }
                finally {
                    if(reader!=null) {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            log.error(e.getMessage(),e);
                        }
                    }
                    if(out!=null) {
                        out.close();
                    }
                    log.info("=====notify->from->wx end("+uuid+"):"+(System.currentTimeMillis()-start));
                }
                return;
            }



            //逻辑处理 TODO: 数据库操作 ？？？

            //回调订单系统 openfeign
            // 创建订单系统 0-1
            // 多库-多表
            // openfeign 进程直接的调用
            // 日志打印

            //微信通知了我，【我要通知订单系统】
            //订单系统提供一下接口,参数{订单号,支付状态}



            retunCode = 200;
            msg = "成功";
        } catch (Exception e) {
            msg ="回调处理失败";

        }
        //------返回
        PrintWriter out = null;
        try {
            String returnCode = retunCode==200 ?"SUCCESS":"FAIL";
            builder = new StringBuilder();
            response.setContentType("text/xml;charset=utf-8");
            out = response.getWriter();
            builder.append("<xml>\n");
            builder.append("  <return_code><![CDATA["+returnCode+"]]></return_code>\n");
            builder.append("	<return_msg><![CDATA["+msg+"]]></return_msg>\n");
            builder.append("</xml>\n");

            log.info("=====返回数据 sb={}",builder.toString());
            out.write(builder.toString());
            out.flush();
        } catch (IOException e) {

            log.error("=====notify->from->wx error("+uuid+"):"+e.getMessage(),e);
        }
        finally {
            if(reader!=null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error(e.getMessage(),e);
                }
            }
            if(out!=null) {
                out.close();
            }
            log.info("=====notify->from->wx end("+uuid+"):"+(System.currentTimeMillis()-start));
        }
    }
}
